package valatile;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Aug28-tlsjn
 * @date 2021-04-11 Sunday 10:46
 */
public class VolatileDemo {
  public static void main(String[] args) {
    MyData myData = new MyData();
    ExecutorService executorService = ThreadUtils.getExecutorService(20, 25, 3, 3);
    for (int i = 0; i < 20; i++) {
      executorService.execute(() -> {
        for (int j = 0; j < 1000; j++) {
          myData.addPlusPlus();
          myData.addMyAtomic();
        }
      });
    }

    try {
      TimeUnit.SECONDS.sleep(10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("Main Thread: " + myData.num);
    System.out.println("Main Thread: " + myData.atomicInteger.get());
    executorService.shutdown();
  }

  /**
   * 演示 volatile 能保证的可见性
   */
  private static void seeOKByVolatile() {
    MyData myData = new MyData();
    ExecutorService executorService = ThreadUtils.getExecutorService(3, 5, 3, 3);
    executorService.execute(() -> {
      System.out.println(Thread.currentThread().getName() + "\t come in...");
      try {
        TimeUnit.SECONDS.sleep(3);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      myData.addTo60();
      System.out.println(Thread.currentThread().getName() + "\t updated number valued: " + myData.num);
    });

    while (myData.num == 0) {

    }
    System.out.println(Thread.currentThread().getName() + "\t mission is over. Main thread get number valued " + myData.num);
    executorService.shutdown();
  }
}

class MyData {
  volatile int num = 0;
  public void addTo60() {
    this.num = 60;
  }
  public void addPlusPlus() {
    this.num++;
  }

  AtomicInteger atomicInteger = new AtomicInteger();

  public void addMyAtomic() {
    this.atomicInteger.getAndIncrement();
  }
}
